package com.tingyuge.base.thread.pool;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author zhangqiuping
 * @version 1.0
 * coreSize 核心线程数
 * maximumPoolSize 线程池中最大线程数
 * keepLiveTime: 最大线程数-coresize的这些线程的没有任务执行的时候,的存活时间
 * timeUnit: 时间单位
 * blockingQueue 实现有多种,就是阻塞队列
 * threadFactory:  线程工厂,用户创建新的线程并被线程池所管理.默认线程工厂素有创建的线程都是用户线程,且优先级为正常的优先级
 * RejectedExecutionHandler:
 * 1.abortPolicy:直接抛出一个异常
 * 2.DiscardPolicy 什么都不做
 * 3.discardOldPolicy  丢到最早的任务,在把任务放进去---可以扔到消息队列.然后再扔会线程池
 * 4.callRunsPolicy: 直接由提交任务的线程来运行这个任务...
 * 在使用线程池的时候,最好将偏向锁关闭,因为我们肯定是不同的线程执行任务!
 */
public class ThreadPoolUtil {
    private static final int DEFAULT_CORE_SIZE = 3;
    private static final int MAX_MUM_SIZE = 5;
    private static final int KEEP_ALIVE_TIME = 0;
    private static final int BLOCK_SIZE = 3;

    private volatile static ThreadPoolExecutor executor;

    // 获取单例的线程池对象
    public static ThreadPoolExecutor getInstance(String threadName) {
        if (executor == null) {
            synchronized (ThreadPoolUtil.class) {
                if (executor == null) {
                    executor = new ThreadPoolExecutor(DEFAULT_CORE_SIZE,// 核心线程数
                            MAX_MUM_SIZE, // 最大线程数
                            KEEP_ALIVE_TIME, // 闲置线程存活时间
                            TimeUnit.SECONDS,// 时间单位
                            new LinkedBlockingDeque<Runnable>(BLOCK_SIZE),// 线程队列
                            new ThreadFactoryBuilder().setNameFormat(threadName + "-thread-pool-%d").build()
                            , new CustomCallerRunsPolicy()
                    );
                }
            }
        }
        return executor;
    }

    public static String getClassAndMethod() {
        String className = Thread.currentThread().getStackTrace()[1].getClassName();

        String currentMethod = Thread.currentThread().getStackTrace()[1].getMethodName();

        int currentLine = Thread.currentThread().getStackTrace()[1].getLineNumber();
        return className + "-" + currentMethod + "-" + currentLine;
    }


    public static class CustomCallerRunsPolicy implements RejectedExecutionHandler {
        public CustomCallerRunsPolicy() {
        }

        /**
         *
         * @param r 接受一个线程
         * @param e
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                try {
                    e.getQueue().put(r);
                    Thread.sleep(10);
                    System.out.println("拒绝策略" + e.getQueue().size());
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
             /*   System.out.println("拒绝策略执行,调用当前线程"+Thread.currentThread().getName());
                r.run();*/
            }
        }
    }
}

